import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
import { JhiLanguageService } from 'ng-jhipster';
import { SessionStorageService } from 'ngx-webstorage';
import * as $ from 'jquery';

import { VERSION } from 'app/app.constants';
import { JhiLanguageHelper, AccountService, LoginModalService, LoginService } from 'app/core';
import { ProfileService } from '../profiles/profile.service';

@Component({
    selector: 'jhi-navbar',
    templateUrl: './navbar.component.html',
    styleUrls: ['navbar.scss']
})
export class NavbarComponent implements OnInit {
    inProduction: boolean;
    isNavbarCollapsed: boolean;
    languages: any[];
    swaggerEnabled: boolean;
    modalRef: NgbModalRef;
    version: string;

    constructor(
        private loginService: LoginService,
        private languageService: JhiLanguageService,
        private languageHelper: JhiLanguageHelper,
        private sessionStorage: SessionStorageService,
        private accountService: AccountService,
        private loginModalService: LoginModalService,
        private profileService: ProfileService,
        private router: Router
    ) {
        this.version = VERSION ? 'v' + VERSION : '';
        this.isNavbarCollapsed = true;
    }

    ngOnInit() {
        this.languageHelper.getAll().then(languages => {
            this.languages = languages;
        });

        this.profileService.getProfileInfo().then(profileInfo => {
            this.inProduction = profileInfo.inProduction;
            this.swaggerEnabled = profileInfo.swaggerEnabled;
        }); 
        this.collapsible();
       /* Responsive menu show/hide */
	  $('.responsive_menu a').click(function() {
	    if($('#main_navigation > div').length > 0) {
	      if($('#main_navigation > div').is(":hidden")) {
	        $('#main_navigation > div').slideDown();
	      } else {
	        $('#main_navigation > div').slideUp();
	      }
	      return false;
	    }
	
	    if($('#top_navigation').length > 0) {
	      if($('#top_navigation').is(':hidden')) {
	        $('#top_navigation').slideDown();
	      } else {
	        $('#top_navigation').slideUp();
	      }
	      return false;
	    }
	  });
	   
	   //* If main navigation doesn't exist eet content margin-left to 0 *//
	  function mainNav() {
	    if($('#main_navigation').length === 0) {
	      $('#content').css('margin-left', '0px')
	    }
	  }
	  mainNav();
	   
	  //* Main menu functions *//
	  $('ul.main > li').each(function() {
	    var sub_main = $(this).find('ul');
	    
	    if (sub_main.length > 0) {
	      $(this).children('a').addClass('expand');
	      $(this).children('a').append('<span class="count"><fa-icon icon="plus"></fa-icon></span>');
	    }
	   
	  });
	   $('.expand').collapsible({
	    defaultOpen: 'current,third',
	    cookieName: 'navAct',
	    cssOpen: 'subOpened',
	    cssClose: 'subClosed',
	    speed: 200
	  });
    }

    changeLanguage(languageKey: string) {
        this.sessionStorage.store('locale', languageKey);
        this.languageService.changeLanguage(languageKey);
    }

    collapseNavbar() {
        this.isNavbarCollapsed = true;
    }

    isAuthenticated() {
        return this.accountService.isAuthenticated();
    }

    login() {
        this.modalRef = this.loginModalService.open();
    }

    logout() {
        this.collapseNavbar();
        this.loginService.logout();
        this.router.navigate(['']);
    }

    toggleNavbar() {
        this.isNavbarCollapsed = !this.isNavbarCollapsed;
    }

    getImageUrl() {
        return this.isAuthenticated() ? this.accountService.getImageUrl() : null;
    }
	collapsible() {
		$.fn.collapsible = function (cmd, arg) {
	
	        //firewalling
	        if (!this || this.length < 1) {
	            return this;
	        }
	
	        //address command requests
	        if (typeof cmd == 'string') {
	            return $.fn.collapsible.dispatcher[cmd](this, arg);
	        }
	        
	        //return the command dispatcher
	        return $.fn.collapsible.dispatcher['_create'](this, cmd);
	    };
	
	    //create the command dispatcher
	    $.fn.collapsible.dispatcher = {
	
	        //initialized with options
	        _create : function(obj, arg) {
	            createCollapsible(obj, arg);
	        },
	
	        //toggle the element's display
	        toggle: function(obj) {
	            toggle(obj, loadOpts(obj));
	            return obj;
	        },
	
	        //show the element
	        open: function(obj) {
	            open(obj, loadOpts(obj));
	            return obj;
	        },
	
	        //hide the element
	        close: function(obj) {
	            close(obj, loadOpts(obj));
	            return obj;
	        },
	
	        //check if the element is closed
	        collapsed: function(obj) {
	            return collapsed(obj, loadOpts(obj));
	        },
	
	        //open all closed containers
	        openAll: function(obj) {
	            return openAll(obj, loadOpts(obj));
	        },
	
	        //close all opened containers
	        closeAll: function(obj) {
	            return closeAll(obj, loadOpts(obj));
	        }
	    };
	
	    //create the initial collapsible
	    function createCollapsible(obj, options)
	    {
	
	        //build main options before element iteration
	        var opts = $.extend({}, $.fn.collapsible.defaults, options);
	        
	        //store any opened default values to set cookie later
	        var opened = [];
	        
	        //iterate each matched object, bind, and open/close
	        obj.each(function() {
	
	            var $this = $(this);
	            saveOpts($this, opts);
	            
	            //bind it to the event
	            if (opts.bind == 'mouseenter') {
	
	                $this.bind('mouseenter', function(e) {
	                    e.preventDefault(); 
	                    toggle($this, opts);
	                });
	            }
	            
	            //bind it to the event
	            if (opts.bind == 'mouseover') {
	
	                $this.bind('mouseover',function(e) {
	                    e.preventDefault(); 
	                    toggle($this, opts); 
	                });
	            }
	            
	            //bind it to the event
	            if (opts.bind == 'click') {
	
	                $this.bind('click', function(e) {
	                    e.preventDefault();
	                    toggle($this, opts);
	                });
	
	            }
	            
	            //bind it to the event
	            if (opts.bind == 'dblclick') {
	
	                $this.bind('dblclick', function(e) {
	
	                    e.preventDefault();
	                    toggle($this, opts);
	                });
	
	            }
	            
	            //initialize the collapsibles
	            //get the id for this element
	            var id = $this.attr('id');
	            
	            //if not using cookies, open defaults
	            if (!useCookies(opts)) {
	
	                //is this collapsible in the default open array?
	                var dOpenIndex = inDefaultOpen(id, opts);
	                
	                //close it if not defaulted to open
	                if (dOpenIndex === false) {
	
	                    $this.addClass(opts.cssClose);
	                    opts.loadClose($this, opts);
	
	                } else { //its a default open, open it
	
	                    $this.addClass(opts.cssOpen);
	                    opts.loadOpen($this, opts);
	                    opened.push(id);
	                }
	
	            } else { //can use cookies, use them now
	
	                //has a cookie been set, this overrides default open
	                if (issetCookie(opts)) {
	
	                    var cookieIndex = inCookie(id, opts);
	
	                    if (cookieIndex === false) {
	
	                        $this.addClass(opts.cssClose);
	                        opts.loadClose($this, opts);
	
	                    } else {
	
	                        $this.addClass(opts.cssOpen);
	                        opts.loadOpen($this, opts);
	                        opened.push(id);
	                    }
	
	                } else { //a cookie hasn't been set open defaults, add them to opened array
	
	                    dOpenIndex = inDefaultOpen(id, opts);
	
	                    if (dOpenIndex === false) {
	
	                        $this.addClass(opts.cssClose);
	                        opts.loadClose($this, opts);
	
	                    } else {
	
	                        $this.addClass(opts.cssOpen);
	                        opts.loadOpen($this, opts);
	                        opened.push(id);
	                    }
	                }
	            }
	        });
	        
	        //now that the loop is done, set the cookie
	        if (opened.length > 0 && useCookies(opts)) {
	
	            setCookie(opened.toString(), opts);
	
	        } else { //there are none open, set cookie
	
	            setCookie('', opts);
	        }
	        
	        return obj;
	    }
	    
	    //load opts from object
	    function loadOpts($this) {
	        return $this.data('collapsible-opts');
	    }
	    
	    //save opts into object
	    function saveOpts($this, opts) {
	        return $this.data('collapsible-opts', opts);
	    }
	    
	    //returns true if object is opened
	    function collapsed($this, opts) {
	        return $this.hasClass(opts.cssClose);
	    }
	    
	    //hides a collapsible
	    function close($this, opts) {
	
	        //give the proper class to the linked element
	        $this.addClass(opts.cssClose).removeClass(opts.cssOpen);
	        
	        //close the element
	        opts.animateClose($this, opts);
	        
	        //do cookies if plugin available
	        if (useCookies(opts)) {
	            // split the cookieOpen string by ","
	            var id = $this.attr('id');
	            unsetCookieId(id, opts);
	        }
	    }
	    
	    //opens a collapsible
	    function open($this, opts) {
	
	        //give the proper class to the linked element
	        $this.removeClass(opts.cssClose).addClass(opts.cssOpen);
	        
	        //open the element
	        opts.animateOpen($this, opts);
	        
	        //do cookies if plugin available
	        if (useCookies(opts)) {
	
	            // split the cookieOpen string by ","
	            var id = $this.attr('id');
	            appendCookie(id, opts);
	        }
	    }
	    
	    //toggle a collapsible on an event
	    function toggle($this, opts) {
	
	        if (collapsed($this, opts)) {
	
	            //open a closed element
	            open($this, opts);
	
	        } else {
	
	            //close an open element
	            close($this, opts);
	        }
	        
	        return false;
	    }
	
	    //open all closed containers
	    function openAll($this, opts) {
	
	        // loop through all container elements
	        $.each($this, function(elem, value) {
	
	            if (collapsed($(value), opts)) {
	
	                //open a closed element
	                open($(value), opts);
	            }
	        });
	    }
	
	    //close all open containers
	    function closeAll($this, opts) {
	
	        $.each($this, function(elem, value) {
	
	            if (!collapsed($(value), opts)) {
	
	                //close an opened element
	                close($(value), opts);
	            }
	        });
	    }
	    
	    //use cookies?
	    function useCookies(opts) {
	
	        //return false if cookie plugin not present or if a cookie name is not provided
	        if (!$.cookie || opts.cookieName == '') {
	            return false;
	        }
	        
	        //we can use cookies
	        return true;
	    }
	    
	    //append a collapsible to the cookie
	    function appendCookie(value, opts) {
	
	        //check if cookie plugin available and cookiename is set
	        if (!useCookies(opts)) {
	            return false;
	        }
	        
	        //does a cookie already exist
	        if (!issetCookie(opts)) {
	
	            //no lets set one
	            setCookie(value, opts);
	            return true;
	        }
	        
	        //cookie already exists, is this collapsible already set?
	        if (inCookie(value, opts)) { //yes, quit here
	            return true;
	        }
	        
	        //get the cookie
	        var cookie = decodeURIComponent($.cookie(opts.cookieName));
	
	        //turn it into an array
	        var cookieArray = cookie.split(',');
	        
	        //add it to list
	        cookieArray.push(value);
	        
	        //save it
	        setCookie(cookieArray.toString(), opts);
	        
	        return true;    
	    }
	    
	    //unset a collapsible from the cookie
	    function unsetCookieId(value, opts)
	    {
	        //check if cookie plugin available and cookiename is set
	        if (!useCookies(opts)) {
	            return false;
	        }
	        
	        //if its not there we don't need to remove from it
	        if (!issetCookie(opts)) { //quit here, don't have a cookie 
	            return true;
	        }
	        
	        //we have a cookie, is this collapsible in it
	        var cookieIndex = inCookie(value, opts);
	        if (cookieIndex === false) { //not in the cookie quit here
	            return true;
	        }
	        
	        //still here get the cookie
	        var cookie = decodeURIComponent($.cookie(opts.cookieName));
	        
	        //turn it into an array
	        var cookieArray = cookie.split(',');
	        
	        //lets pop it out of the array
	        cookieArray.splice(cookieIndex, 1);
	
	        //overwrite
	        setCookie(cookieArray.toString(), opts);
	
	        return true
	    }
	    
	    //set a cookie
	    function setCookie(value, opts)
	    {
	        //can use the cookie plugin
	        if (!useCookies(opts)) { //no, quit here
	            return false;
	        }
	        
	        //cookie plugin is available, lets set the cookie
	        $.cookie(opts.cookieName, value, opts.cookieOptions);
	
	        return true;
	    }
	    
	    //check if a collapsible is in the cookie
	    function inCookie(value, opts)
	    {
	        //can use the cookie plugin
	        if (!useCookies(opts)) {
	            return false;
	        }
	        
	        //if its not there we don't need to remove from it
	        if (!issetCookie(opts)) { //quit here, don't have a cookie 
	            return false;
	        }
	
	        //get the cookie value
	        var cookie = decodeURIComponent($.cookie(opts.cookieName));
	        
	        //turn it into an array
	        var cookieArray = cookie.split(',');
	        
	        //get the index of the collapsible if in the cookie array
	        var cookieIndex = $.inArray(value, cookieArray);
	        
	        //is this value in the cookie array
	        if (cookieIndex == -1) { //no, quit here
	            return false;
	        }
	        
	        return cookieIndex;
	    }
	    
	    //check if a cookie is set
	    function issetCookie(opts)
	    {
	        //can we use the cookie plugin
	        if (!useCookies(opts)) { //no, quit here
	            return false;
	        }
	        
	        //is the cookie set
	        if ($.cookie(opts.cookieName) === null) { //no, quit here
	            return false;
	        }
	        
	        return true;
	    }
	    
	    //check if a collapsible is in the list of collapsibles to be opened by default
	    function inDefaultOpen(id, opts)
	    {
	        //get the array of open collapsibles
	        var defaultOpen = getDefaultOpen(opts);
	        
	        //is it in the default open array
	        var index = $.inArray(id, defaultOpen);
	        if (index == -1) { //nope, quit here
	            return false;
	        }
	        
	        return index;
	    }
	    
	    //get the default open collapsibles and return array
	    function getDefaultOpen(opts)
	    {
	        //initialize an empty array
	        var defaultOpen = [];
	        
	        //if there is a list, lets split it into an array
	        if (opts.defaultOpen != '') {
	            defaultOpen = opts.defaultOpen.split(',');
	        }
	        
	        return defaultOpen;
	    }
	    
	    // settings
	    $.fn.collapsible.defaults = {
	        cssClose: 'collapse-close', //class you want to assign to a closed collapsible header
	        cssOpen: 'collapse-open', //class you want to assign an opened collapsible header
	        cookieName: 'collapsible', //name of the cookie you want to set for this collapsible
	        cookieOptions: { //cookie options, see cookie plugin for details
	            path: '/',
	            expires: 7,
	            domain: '',
	            secure: ''
	        },
	        defaultOpen: '', //comma separated list of header ids that you want opened by default
	        speed: 'slow', //speed of the slide effect
	        bind: 'click', //event to bind to, supports click, dblclick, mouseover and mouseenter
	        animateOpen: function (elem, opts) { //replace the standard slideUp with custom function
	            elem.next().stop().slideDown(opts.speed);
	        },
	        animateClose: function (elem, opts) { //replace the standard slideDown with custom function
	            elem.next().stop().slideUp(opts.speed);
	        },
	        loadOpen: function (elem, opts) { //replace the default open state with custom function
	            elem.next().show();
	        },
	        loadClose: function (elem, opts) { //replace the default close state with custom function
	            elem.next().hide();
	        }
	    };
	}
}
